#include "klient.hpp"
#include "oknoglowne.h"
#include <map>
#include <vector>

using namespace System;
using namespace System::Threading;

Klient::Klient(OknoGlowne^ okno) {
   ioService = new boost::asio::io_service();
   klient = new KlientTCP(*ioService);
   this->okno = okno;
}

Klient::~Klient() {
   delete klient;
   delete ioService;
}

void Klient::polacz(std::string adres, std::string port) {
   klient->polacz(adres, port);
   watek = gcnew Thread (gcnew ThreadStart (this,&Klient::odbieranie));
   watek->Start();
}

void Klient::wyslij(std::string dane) {
   klient->wyslij(dane);
}

void Klient::zamknij() {
   klient->zamknij();
}

void Klient::odbieranie() {
   std::string wiadomosc;
   for(;;) {
      try {	 
	 wiadomosc = klient->odbierz();
	 
	 //najpierw sprawdzenie, czy ramka jest poprawna
	 std::vector<std::string> ramki = Ramka::podzielNaRamki(wiadomosc);
	 std::vector<std::string>::iterator it = ramki.begin();
	 for(; it != ramki.end(); ++it) {
		Ramka ramka;
		try {
		    ramka.sprawdzRamkeOdebrana(*it);
		    nowaRamka(ramka);
		} catch (...) {
			// ramka byla bledna wiec ja ignorujemy i czekamy dalej
		}
	 }

      } catch(...) {
	 break; //przerywamy for, wiec watek powinien zakonczyc dzialanie...
      }
   }
}

void Klient::nowaRamka(Ramka ramka) {   
   int temp = ramka.pobierzTemat();
   krokSym_d^ krokSymDelegat = gcnew krokSym_d(okno, &OknoGlowne::dodajPktWykresu);
   dodajRegulator_d^ dodajRegulatorDelegat = gcnew dodajRegulator_d(okno, &OknoGlowne::dodajRegulator);
   dodajObiekt_d^ dodajObiektDelegat = gcnew dodajObiekt_d(okno, &OknoGlowne::dodajObiekt);
   dodajListeGeneratorow_d^ dodajGeneratoryDelegat = gcnew dodajListeGeneratorow_d(okno, &OknoGlowne::dodajListeGeneratorow);
   dodajMapeGeneratorow_d^ dodajMapeGenDelegat = gcnew dodajMapeGeneratorow_d(okno, &OknoGlowne::dodajMapeGeneratorow);   
   dodajMapeRegulatorow_d^ dodajMapeRegDelegat = gcnew dodajMapeRegulatorow_d(okno, &OknoGlowne::dodajMapeRegulatorow);
   dodajMapeObiektow_d^ dodajMapeObDelegat = gcnew dodajMapeObiektow_d(okno, &OknoGlowne::dodajMapeObiektow);

   cliext::vector<double> wekt;
   cliext::vector<double>::iterator it;
   double x1, x2, x3, x4;

   switch(temp) {
   case TematKomunikacji::NowyKrokSymulacjiTCP: {//byl problem z rzutowaniem na enum, wiec sie z tego wycofalem 
	   wekt = Ramka::zamienStringNaWektorDouble(ramka.pobierzDane());	  
      okno->Invoke(krokSymDelegat,gcnew array<System::Object^>(4){*(wekt.begin()),*(wekt.begin()+1),*(wekt.begin()+2),*(wekt.begin()+3)});
	   
      break;
   }
   case TematKomunikacji::zmianaObiektuTCP: {
	   konfigObiektu = Ramka::zamienStringNaMape(ramka.pobierzDane());
	   okno->Invoke(dodajObiektDelegat,gcnew array<System::Object^>(0){});
      
      break;
	}
   case TematKomunikacji::zmianaRegulatoraTCP: {
	   konfigRegulatora = Ramka::zamienStringNaMape(ramka.pobierzDane());
	   okno->Invoke(dodajRegulatorDelegat,gcnew array<System::Object^>(0){});      
      break;
	}
   case TematKomunikacji::zmianaWartosciZadanejTCP:
      //okno->zmianaWartZad(Ramka::zamienStringNaMape(ramka.pobierzDane()));
      break;
   case TematKomunikacji::nowaMapaObiektowTCP: {
	   mapaObiektow = Ramka::zamienStringNaMapeCLI(ramka.pobierzDane());
	   okno->Invoke(dodajMapeObDelegat, gcnew array<System::Object^>(0){}); 
      //okno->nowaMapaObiektow(Ramka::zamienStringNaMapeCLI(ramka.pobierzDane()));
      break;
		   }
   case TematKomunikacji::nowaMapaRegulatorowTCP: {
	   mapaRegulatorow = Ramka::zamienStringNaMapeCLI(ramka.pobierzDane());
	   okno->Invoke(dodajMapeRegDelegat, gcnew array<System::Object^>(0){}); 

   //   okno->nowaMapaRegulatorow(Ramka::zamienStringNaMapeCLI
	//		       (ramka.pobierzDane()));
      break;
		   }
   case TematKomunikacji::nowaMapaWartZadTCP: {
	   mapaGeneratorow = Ramka::zamienStringNaMapeCLI(ramka.pobierzDane());
	   okno->Invoke(dodajMapeGenDelegat, gcnew array<System::Object^>(0){}); 

      //okno->nowaMapaWartZad(Ramka::zamienStringNaMapeCLI(ramka.pobierzDane()));
      break;
		   }
   case TematKomunikacji::nowaListaUstawionychGeneratorowTCP: {
	   wektorGeneratorow = Ramka::zamienStringNaWektorCLI(ramka.pobierzDane());
	   okno->Invoke(dodajGeneratoryDelegat,gcnew array<System::Object^>(0){});      

      //okno->nowaListaUstawionychGeneratorow(Ramka::zamienStringNaWektorCLI
		//			    (ramka.pobierzDane()));
      break;
		   }
   case TematKomunikacji::czyscRegulatorTCP:
      okno->czyscRegulator();
      break;
   case TematKomunikacji::czyscObiektTCP:
      //okno->czyscObiekt();
      break;
   case TematKomunikacji::resetSymulacjiTCP:
	  okno->Reset();
      break;

   
   }
}
cliext::map<System::String^,System::String^> Klient::pobierzObiekt() {
	return konfigObiektu;
}
cliext::map<System::String^,System::String^> Klient::pobierzRegulator() {
	return konfigRegulatora;
}


void Klient::zaloguj(std::string login, std::string haslo) {
   klient->wyslij(Ramka::stworzRamkeDoWyslania(logowanieTCP,login + "#" + haslo));
   //Thread::Sleep(100);
   //klient->wyslij(Ramka::stworzRamkeDoWyslania(nowaMapaObiektowTCP,std::string()));
   //Thread::Sleep(100);
   /*klient->wyslij(Ramka::stworzRamkeDoWyslania(nowaMapaRegulatorowTCP,std::string()));
   //Thread::Sleep(100);
   klient->wyslij(Ramka::stworzRamkeDoWyslania(nowaMapaWartZadTCP,std::string()));*/

}

cliext::vector<System::String^> Klient::pobierzGeneratory() {
	return wektorGeneratorow;
}

cliext::map<System::String^,int> Klient::pobierzMapeRegulatorow() {
	return mapaRegulatorow;
}
   cliext::map<System::String^,int> Klient::pobierzMapeGeneratorow() {
	   return mapaGeneratorow;
   }
   cliext::map<System::String^,int> Klient::pobierzMapeObiektow() {
	   return mapaObiektow;
   }

   void Klient::symulatorStart() {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::startSymulacjiTCP,std::string()));
   }

   void Klient::symulatorReset() {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::resetSymulacjiTCP,std::string()));
     }

   void Klient::symulatorStop() {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::stopSymulacjiTCP,std::string()));
   }

   void Klient::ustawRegulator(System::String^ nazwa) {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::zmianaRegulatoraTCP,Ramka::ToStdString(nazwa)));

}

   void Klient::dodajWartZad(System::String^ nazwa) {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::nowaListaUstawionychGeneratorowTCP,Ramka::ToStdString(nazwa)));

   }

      void Klient::ustawObiekt(System::String^ nazwa) {
	   klient->wyslij(Ramka::stworzRamkeDoWyslania(TematKomunikacji::zmianaObiektuTCP,Ramka::ToStdString(nazwa)));

}